package com.example.springboot.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.example.springboot.controller.request.BaseRequest;
import com.example.springboot.controller.request.savePestRequest;
import com.example.springboot.entity.Pest;
import com.example.springboot.entity.PestImage;
import com.example.springboot.exception.FileDeleteException;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.mapper.PestImageMapper;
import com.example.springboot.mapper.PestMapper;
import com.example.springboot.service.IPestService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.minio.MinioClient;
import io.minio.RemoveObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class PestService implements IPestService {

    @Resource
    private PestMapper pestMapper;

    @Autowired
    private PestImageMapper pestImageMapper;

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.bucketName}")
    private String bucketName;

    /**
     * 获取所有虫害信息
     *
     * @return 虫害信息列表
     */
    @Override
    public List<Pest> list() {
        return pestMapper.list();
    }

    /**
     * 分页查询
     *
     * @param baseRequest 请求参数
     * @return 分页结果
     */
    @Override
    public PageInfo<Pest> page(BaseRequest baseRequest) {
        PageHelper.startPage(baseRequest.getPageNum(), baseRequest.getPageSize());
        return new PageInfo<>(pestMapper.listByCondition(baseRequest));
    }


    /**
     * 保存虫害信息并返回id(作为pest_id关联图片)
     * @param obj
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer save(savePestRequest obj) {
        try {
            Pest pest = new Pest();
            pest.setCreateTime(LocalDate.now());
            pest.setUpdateTime(LocalDate.now());
            pest.setCategory(category(obj.getCategories()));
            BeanUtils.copyProperties(obj, pest);
            pestMapper.save(pest); // 插入后应能获取生成的 ID
            return pest.getId(); // 返回生成的 pestId
        } catch (Exception e) {
            throw new ServiceException("数据插入错误", e);
        }
    }
    /**
     * 批量添加图片并更新数据库(添加数据库url以及minio对应存储图片)
     *
     * @param pestId id
     * @param imageUrls 图片url
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addImagesToPest(Integer pestId, List<String> imageUrls) {
        List<PestImage> images = new ArrayList<>();
        for (String url : imageUrls) {
            PestImage image = new PestImage();
            image.setPestId(pestId);
            image.setImageUrl(url);
            image.setCreatedTime(LocalDateTime.now());
            images.add(image);
        }
        if (!images.isEmpty()) {
            pestImageMapper.insertBatch(images);
        }
    }


    /**
     * 根据id获取虫害信息
     *
     * @param id id
     * @return 虫害信息
     */
    @Override
    public Pest getById(Integer id) {
        return pestMapper.getById(id);
    }

    /**
     * 更新虫害信息
     *
     * @param obj obj
     */
    @Override
    public void update(savePestRequest obj) {
        try {
            Pest pest = new Pest();
            pest.setCategory(category(obj.getCategories()));
            pest.setUpdateTime(LocalDate.now());
            BeanUtils.copyProperties(obj, pest);
            pestMapper.updateById(pest);
        } catch (Exception e) {
            throw new ServiceException("数据更新错误", e);
        }

    }


    /**
     * 批量删除虫害并将关联图片删除
     *
     * @param id id
     */
    @Override
    public void deleteById(Integer id) {
        // 先删除图片
        pestImageMapper.deleteByPestId(id);
        // 再删除虫害
        pestMapper.deleteById(id);
    }

    /**
     * 删除单个图片并更新数据库,(删除数据库url以及minio对应存储图片)
     *
     * @param id id
     */
    @Override
    public void deleteImage(Integer id) {
        String url = pestImageMapper.getUrlById(id);
        if (url != null) {
            try {
                // 解析 URL 获取 objectName（如：/pest-images/abc.jpg）
                URI uri = new URI(url);

                String path = uri.getPath(); // 获取路径部分
                log.info("单个删除模式URL: {}", url);
//                String objectName = path.startsWith("/") ? path.substring(1) : path; // 去掉开

                Path p = Paths.get(path.startsWith("/") ? path.substring(1) : path); // 去掉开头的 '/'
                String objectName = p.getFileName().toString();
                log.info("单个删除模式 MinIO 文件：{}", objectName);

                minioClient.removeObject( RemoveObjectArgs.builder()
                                .bucket(bucketName)
                                .object(objectName)
                                .build()
                        );
                pestImageMapper.deleteById(id);
            } catch (Exception e) {
                log.error("URL 解析错误", e);
                throw new FileDeleteException("图片删除错误", e);
            }
        }
    }

    /**
     * 批量删除图片并更新数据库(删除数据库url以及minio对应存储图片)
     *目前没在使用
     * @param pestId id
     */
    @Override
    @Transactional
    public void deleteImagesByPestId(Integer pestId) {
        List<String> urls = pestImageMapper.findByPestId(pestId);

        for (String url : urls) {
            try {
                // 解析 URL 获取 objectName（如：/pest-images/abc.jpg）
                URI uri = new URI(url);
                String path = uri.getPath(); // 获取路径部分
                log.info("URL: {}", url);
                Path p = Paths.get(path.startsWith("/") ? path.substring(1) : path); // 去掉开头的 '/'
                String objectName = p.getFileName().toString();
                log.info("删除 MinIO 文件：{}", objectName);

                // 调用 MinIO 删除接口
                minioClient.removeObject(
                        RemoveObjectArgs.builder()
                                .bucket(bucketName)
                                .object(objectName)
                                .build()
                );
            } catch (Exception e) {
                log.error("删除 MinIO 文件 [{}] 失败", url, e);
            }
        }
        log.info("删除 MinIO 文件成功");
        log.info("bucketName：{} ", bucketName);
        pestImageMapper.deleteByPestId(pestId);
        log.info("删除数据库文件成功");
    }


    /**
     * 获取分类category的名称（由categories拼接而成）
     *
     * @param categories 分类列表
     * @return 分类名称
     */
    private String category(List<String> categories) {
        StringBuilder sb = new StringBuilder();
        if (CollUtil.isNotEmpty(categories)) {
            categories.forEach(v -> sb.append(v).append(" > "));
            return sb.substring(0, sb.lastIndexOf(" > "));
        }
        return sb.toString();
    }



}
